package com.iims.flowable.service.impl;

import cn.hutool.core.lang.Validator;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.iims.common.constant.UserConstants;
import com.iims.common.utils.spring.SpringUtils;
import com.iims.flowable.flow.domain.FlowableForm;
import com.iims.flowable.flow.vo.request.DeployFormRequest;
import com.iims.flowable.mapper.FlowFormMapper;
import com.iims.flowable.service.IFlowFormService;
import org.flowable.common.engine.api.FlowableException;
import org.flowable.common.engine.api.FlowableObjectNotFoundException;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.DeploymentBuilder;
import org.flowable.engine.repository.ProcessDefinition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;


/**
 * 流程表单Service业务层处理
 *
 * @author fanpei
 * @date 2021-04-03
 */
@Service
public class FlowFormServiceImpl extends ServiceImpl<FlowFormMapper, FlowableForm> implements IFlowFormService {
    //@Autowired
    //private FlowFormDefinitionMapper definitionMapper;

    @Autowired
    private RepositoryService repositoryService;

    @Override
    public String selectFlowableFormUIByKey(String formKey) {
        FlowableForm flowableForm = selectFlowableFormByKey(formKey);
        if (null == flowableForm)
            return "";
        else
            return flowableForm.getFormJson();
    }

    /**
     * 查询流程表单
     *
     * @param formKey 流程表单ID
     * @return 流程表单
     */
    @Override
    public FlowableForm selectFlowableFormByKey(String formKey) {
        return baseMapper.selectOne(
                new LambdaQueryWrapper<FlowableForm>().eq(FlowableForm::getFormKey, formKey));
    }

    /**
     * 查询流程表单列表
     *
     * @param flowableForm 流程表单
     * @return 流程表单
     */
    @Override
    public List<FlowableForm> selectFlowableFormList(FlowableForm flowableForm) {
        return baseMapper.selectFlowableFormList(flowableForm);
    }

    /**
     * 新增流程表单
     *
     * @param flowableForm 流程表单
     * @return 结果
     */
    @Override
    public int insertFlowableForm(FlowableForm flowableForm) {
        baseMapper.insert(flowableForm);
        /*definitionMapper.insert(new ActFoFormDefinition(flowableForm));*/
        return 1;
    }

    /**
     * 修改流程表单
     *
     * @param flowableForm 流程表单
     * @return 结果
     */
    @Override
    public int updateFlowableForm(FlowableForm flowableForm) {
        baseMapper.updateById(flowableForm);
      /*  ActFoFormDefinition formDefinition = getFormDefinitionByKey(flowableForm.getFormKey());
        ActFoFormDefinition newActDf = new ActFoFormDefinition(flowableForm);
        newActDf.setId(formDefinition.getId());
        definitionMapper.updateById(newActDf);*/
        return 1;
    }

    /**
     * 删除流程表单信息
     *
     * @param formKey 流程表单Key
     * @return 结果
     */
    @Override
    public int deleteFlowableFormById(Long formKey) {
        baseMapper.deleteById(formKey);
/*        definitionMapper.delete(new LambdaQueryWrapper<ActFoFormDefinition>()
                .eq(ActFoFormDefinition::getKey, formKey));*/
        return 1;
    }

    @Override
    public String checkFormNameUnique(FlowableForm form) {
        String formKey = Validator.isNull(form.getFormKey()) ? "" : form.getFormKey();
        FlowableForm info = getOne(new LambdaQueryWrapper<FlowableForm>()
                .eq(FlowableForm::getFormName, form.getFormName()).last("limit 1"));
        if (Validator.isNotNull(info) && formKey.equals(info.getFormKey())) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    @Override
    public void deployForm(DeployFormRequest deployReq) {
        IFlowFormService sysformService = SpringUtils.getBean(FlowFormServiceImpl.class);
        String formKey = deployReq.getFormKey();

        String formKeyDefinition = formKey.replace(".form", "");
        FlowableForm form = sysformService.getById(formKeyDefinition);
        if (form != null && form.getFormJson() != null && form.getFormJson().length() > 0) {
            ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                    .processDefinitionKey(deployReq.getProcessDefinitionKey())
                    .singleResult();
            deployByRepositoryService(formKey, form, processDefinition);
        } else {
            throw new FlowableObjectNotFoundException("Cannot find formJson with formKey " + formKeyDefinition);
        }
    }

    private void deployByRepositoryService(String formKey, FlowableForm form, ProcessDefinition processDefinition) {
        try {
            DeploymentBuilder deploymentBuilder = repositoryService.createDeployment();
            deploymentBuilder.parentDeploymentId(processDefinition.getDeploymentId());
            deploymentBuilder.name(form.getFormName());
            deploymentBuilder.category(processDefinition.getCategory());
            deploymentBuilder.addString(formKey, form.getFormJson());
            Deployment deployment = deploymentBuilder.deploy();
            //部署表单的部署id更改 ac_ge_bytearray
            baseMapper.updateFormDeploymentId(deployment.getId(), deployment.getParentDeploymentId());
            //部署表单的部署id更改 act_fo_form_definition
           /* ActFoFormDefinition formDefinition = getFormDefinitionByKey(formKey);
            if (formDefinition != null) {
                formDefinition.setDeploymentId(deployment.getId());
                definitionMapper.updateById(formDefinition);
            }*/
            //repositoryService.setDeploymentCategory(deployment.getId(), deployment.getCategory());
            //formRepositoryService.setDeploymentCategory(deployment.getId(), deployment.getCategory());
            //repositoryService.setProcessDefinitionCategory(processDefinition.getId(), processDefinition.getCategory());
        } catch (Exception e) {
            if (e instanceof FlowableException) {
                throw (FlowableException) e;
            }
            throw new FlowableException(e.getMessage(), e);
        }
    }
}
